package com.fishingwithme.infrastructure.cfg;

import cn.fishingwithme.domain.spots.*;
import cn.fishingwithme.infrastructure.*;
import com.fishingwithme.domain.spots.*;
import com.fishingwithme.infrastructure.*;
import com.fishingwithme.infrastructure.cfg.types.Deserializers;
import com.fishingwithme.infrastructure.utils.EmailSenderFactory;
import com.fishingwithme.infrastructure.utils.ObjectMapperFactory;
import com.fishingwithme.infrastructure.utils.TencentGeocoderClient;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.csource.fastdfs.*;


import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Value("${tencent_geo_key}")
    private String tencentGeoKey;


    @Value("${spring.mail.host}")
    private String emailHost;
    @Value("${spring.mail.port}")
    private int emailPort;
    @Value("${spring.mail.username}")
    private String emailAddress;
    @Value("${spring.mail.password}")
    private String emailPassword;


    @Value("${spring.mail.properties.mail.smtp.ssl.enable:false}")
    private boolean sslEnabled;

    @Value("${spring.mail.properties.mail.smtp.starttls.enable:false}")
    private boolean tlsEnabled;

    @Value("${fastdfs.config.location}")
    private String configLocation;

    @Bean
    public EmailSenderFactory emailSenderFactory() {
        EmailSenderFactory factory = new EmailSenderFactory();
        factory.setEmailAddress(emailAddress);
        factory.setEmailPassword(emailPassword);
        factory.setEmailHost(emailHost);
        factory.setEmailPort(emailPort);
        factory.setTlsEnabled(tlsEnabled);
        factory.setSslEnabled(sslEnabled);
        return factory;
    }


    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Bean
    public TencentGeocoderClient tencentGeocoderClient(RestTemplate restTemplate) {
        return new TencentGeocoderClient(restTemplate, this.tencentGeoKey);
    }

    @Bean
    public StorageClient1 storageClient() {
        try {
            ClientGlobal.initByProperties(configLocation);
            TrackerClient trackerClient = new TrackerClient();
            TrackerServer trackerServer = trackerClient.getTrackerServer();
            StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);
            return new StorageClient1(trackerServer, storageServer);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    @Bean
    public Jackson2ObjectMapperBuilderCustomizer customizer() {
        return builder -> {
            SimpleModule module = new SimpleModule();
            module.addSerializer(CodeEnum.class, new CodeEnumSerializer());
            module.addSerializer(Boolean.class, new BooleanNumberConverter.Serializer());
            module.addDeserializer(Boolean.class, new BooleanNumberConverter.Deserializer());
            module.addDeserializer(ParkingDistance.class, new Deserializers.ParkingDistanceDeserializer());
            module.addDeserializer(SpotType.class, new Deserializers.SpotTypeDeserializer());
            module.addDeserializer(SpotLvl.class, new Deserializers.SpotLvlDeserializer());
            module.addDeserializer(HarvestType.class, new Deserializers.HarvestTypeDeserializer());
            module.addDeserializer(FishType.class, new Deserializers.FishTypeDeserializer());
            module.addDeserializer(WaterType.class, new Deserializers.WaterTypeDeserializer());
            module.addDeserializer(ScoreType.class, new Deserializers.ScoreTypeDeserializer());

            // 2. 其他全局配置
            builder.featuresToDisable(
                    com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,  // 日期不使用时间戳
                    com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES  // 忽略未知字段
            );
            builder.serializerByType(Long.class, new com.fasterxml.jackson.databind.ser.std.ToStringSerializer());

            // 3. 日期格式配置
            builder.dateFormat(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

            // 4. 空值处理
            builder.serializationInclusion(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL);
            builder.modules(module);
        };


    }

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 添加分页插件（支持MySQL、Oracle等多数据库）
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }

    @Bean
    public ObjectMapperFactory objMapperFactory(){
       return new ObjectMapperFactory();
    }
    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        return configuration ->{

            configuration.getTypeHandlerRegistry().register(
                    new FishTypeListTypeHandler()
            );

            configuration.getTypeHandlerRegistry().register(
                    new SpotTypeListTypeHandler()
            );
        };
    }
}
